#ifndef __THREAD_H__
#define __THREAD_H__

#include <types.h>
#include <list.h>
#include <queue.h>
#include <context.h>

#include <sys/event.h>
#include <sys/ipc.h>
#include <sys/unistd.h>

#define THNAME_MAX  32

struct thread_st {
    context_t ctx;      	/* cpu context of thread */

    list_t link;		/* link in all threads list */
    list_t task_link;		/* link in task threads list */
    queue_t sched_link;		/* link in scheduler threads list */

    int tid;			/* thread ID unique in system */
    char name[THNAME_MAX];
    task_t *owner;      	/* task owner */

    event_t *sleep_evt;	/* sleep for event */
    int sleep_rc;	/* sleep result code */
    int suspend_cnt;	/* thread suspend count */
    int base_prio;
    int prio;           /* thread prioritet */
    int state;          /* current state of thread */
    int sched_lock;     /* locks of scheduler */
    int resched;        /* flag for scheduler */
    int sched_type;	/* scheduler type */

    uint32_t run_time;  /* thread uptime */
    uint32_t time_left; /* quantum */
    
    thread_t *receiver;	/* ID of receiver thread */
    thread_t *sender;	/* ID of sender thread */
    size_t msg_size;	/* size of msg */
    void *msg_addr;	/* addr in kernel space of msg */
    ipc_t *obj_send;
    ipc_t *obj_receive;
    queue_t ipc_link;	/* link in IPC objects list */
    list_t mutexes;	/* list of mutexes in kernel */
    uint32_t nobjects;  /* num of sync objects */
};

/* state of thread */
#define TH_RUN          0x00
#define TH_SLEEP        0x01
#define TH_SUSPEND      0x02
#define TH_EXIT         0x03

/* sleep result */
#define SLEEP_SUCCESS	0	/* success */
#define SLEEP_BREAK	1	/* break due to some reasons */
#define SLEEP_TIMEOUT	2	/* timeout */
#define SLEEP_INVALID	3	/* target event becomes invalid */
#define SLEEP_IRQ	4	/* interrupted by exception */

int thread_create(task_t *, thread_t **);
int thread_terminate(thread_t *);
thread_t *kthread_create(task_t *task, void (*kentry), int prio);
void kthread_terminate(thread_t *);
int thread_load(thread_t *, void (*uentry), void *ustack);
void thread_destroy(thread_t *);
int thread_resume(thread_t *);
int thread_suspend(thread_t *);
thread_t *thread_self(void);
void thread_yield(void);
int thread_valid(thread_t *);
void thread_init(void);

#endif  /* __THREAD_H__ */
